home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
risc_src.lha
/
risc_sources
/
sys
/
gc.t
< prev
next >
Wrap
Text File
|
1990-06-15
|
10KB
|
303 lines
(herald gc
(env tsys
(osys table) ;; %TABLE-VECTOR must be integrated here
(osys gc_weak))) ;; for the GC-WEAK-???-LISTs
(define-integrable (in-old-space? obj)
(and (fx>= obj (system-global slink/old-space-begin))
(fx< obj (system-global slink/old-space-frontier))))
;;; True if an object is in new space.
(define-integrable (in-new-space? obj)
(and (fx>= obj (system-global slink/area-begin))
(fx< obj (system-global slink/area-frontier))))
(define-integrable (maybe-copy-object obj)
(if (not (in-old-space? obj))
obj
(select (descriptor-tag obj)
((tag/fixnum tag/immediate)
obj)
((tag/pair)
(maybe-copy-pair obj))
(else ;extend
(maybe-copy-extend obj)))))
(define (maybe-copy-extend obj)
(let ((header (extend-header obj)))
(cond ((immediate? header)
(copy-immediate-object obj header))
((not (extend? header))
(gc-error-message "corrupt header" obj)
obj)
((in-new-space? header)
header) ;forward
(else
(copy-closure obj header)))))
(define (maybe-copy-pair obj)
(let ((forward (cdr obj)))
(if (and (list? forward) (in-new-space? forward))
forward
(gc-copy-pair obj))))
(define (copy-closure obj template)
(cond ((template-internal-bit? template)
(let* ((encloser (maybe-copy-object (closure-enclosing-object obj)))
(offset (closure-encloser-offset obj)))
(make-pointer encloser (fx- offset 1))))
(else
(let* ((ptrs (template-pointer-slots template))
(size (fx+ ptrs (template-scratch-slots template))))
(gc-copy-extend obj size)))))
(define (gc-copy-template obj)
(let* ((encloser (maybe-copy-object (template-enclosing-object obj)))
(offset (template-encloser-offset obj)))
(make-pointer encloser (fx- offset 1))))
;;; Find out whether a value has been copied into the new heap and return a
;;; a flag and the new location. The flag is true if the object was indeed
;;; retained. This is a simpler version of MOVE-OBJECT. Symbols are always
;;; copied.
(define (get-new-copy obj)
(if (not (in-old-space? obj))
(return t obj)
(xselect (descriptor-tag obj)
((tag/fixnum tag/immediate)
(return t obj))
((tag/pair)
(if (and (list? (cdr obj)) (in-new-space? (cdr obj)))
(return t (cdr obj))
(return nil nil)))
((tag/extend)
(let ((header (extend-header obj)))
(cond ((extend? header)
(get-new-extend-copy obj header))
((symbol? obj)
(return t (gc-copy-object obj)))
(else
(return nil nil))))))))
(define (get-new-extend-copy obj header)
(cond ((template-header? header) ; 68000 requires this first
(receive (traced? new-loc)
(get-new-copy (template-enclosing-object obj))
(if traced?
(return t (make-pointer new-loc
(fx- (template-encloser-offset obj) 1)))
(return nil nil))))
((in-new-space? header)
(return t (extend-header obj)))
((template-internal-bit? header)
(receive (traced? new-loc)
(get-new-copy (closure-enclosing-object obj))
(if traced?
(return t (make-pointer new-loc
(fx- (closure-encloser-offset obj) 1)))
(return nil nil))))
(else
(return nil nil))))
;;; Copy an object and return the new pointer
(define (gc-copy-object thing)
(let* ((begin (system-global slink/area-frontier))
(new (maybe-copy-object thing)))
(gc-scan-heap (gc-extend->pair (gc-extend->pair begin))
(lambda () (system-global slink/area-frontier)))
new))
;;; Moving immediates
(define-local-syntax (fx header)
`(fixnum-ashr ,header 2))
(define (copy-immediate-object obj header)
(select (header-type header)
(((fx header/text) (fx header/symbol) (fx header/bytev))
(gc-copy-extend obj (bytev-cells obj)))
(((fx header/general-vector) (fx header/unit) (fx header/bignum) (fx header/stack))
(gc-copy-extend obj (vector-length obj)))
(((fx header/slice) (fx header/foreign) (fx header/double-float)
(fx header/weak-table))
(gc-copy-extend obj 2))
(((fx header/cell) (fx header/weak-set) (fx header/weak-alist)
(fx header/weak-cell))
(gc-copy-extend obj 1))
(((fx header/template))
(gc-copy-template obj))
(((fx header/vcell))
(gc-copy-extend obj %%vcell-size))
(((fx header/char) 20 (fx header/true) (fx header/interrupt-frame)
(fx header/double-float-vector) (fx header/single-float)
(fx header/ratio) (fx header/complex)
(fx header/fault-frame) 15 (fx header/task)
25 27 29 31)
(gc-error-message "no method for an immediate" obj)
obj)))
;;; Three little utilities.
#|
(define (gc-copy-pair pair)
(gc-count-message)
(let ((new (cons (car pair) (cdr pair))))
(set (cdr pair) new)
new))
(define (gc-copy-extend obj size)
(gc-count-message)
(let ((new (%make-extend (extend-header obj) size)))
(%copy-extend new obj size)
(set (extend-header obj) new)
new))
|#
(define (gc-copy-pair pair)
(lap ()
(load l (d@nil slink/area-frontier) a2)
(add ($ 8) a2)
(store l a2 (d@nil slink/area-frontier))
(sub ($ 5) a2)
(load l (d@r a1 %%car) a4)
(store l a4 (d@r a2 %%car))
(load l (d@r a1 %%cdr) a4)
(store l a4 (d@r a2 %%cdr))
(store l a2 (d@r a1 %%cdr))
(jr link-reg)
(move a2 a1)))
(define (gc-copy-extend obj size)
(lap ()
(load l (d@nil slink/area-frontier) a3)
(add ($ 4) a3)
(add a2 a3 a4)
(store l a4 (d@nil slink/area-frontier))
(add ($ 2) a1 a2)
(sub ($ 2) a3 a1)
(load l (d@r a2 -4) a5)
(store l a5 (d@r a3 -4))
(store l a1 (d@r a2 -4))
(jbr copy-loop-top)
copy-loop
(load l (d@r a2 0) a5)
(store l a5 (d@r a3 0))
(add ($ 4) a2)
(add ($ 4) a3)
copy-loop-top
(j< a3 a4 copy-loop)
(jr link-reg)
(noop)))
(define-integrable (bytev-cells bytev)
(fixnum-ashr (fx+ (bytev-length bytev) 3) 2))
(define (gc-scan-active-heap)
(gc-scan-heap (gc-extend->pair (gc-extend->pair
(system-global slink/area-begin)))
(lambda () (system-global slink/area-frontier))))
(define (gc-scan-initial-impure-area)
(gc-scan-heap (system-global slink/initial-impure-base)
(lambda () (system-global slink/initial-impure-memory-end))))
(define-integrable (gc-scan-heap start stop)
(iterate loop ((obj start))
(cond ((fx>= obj (stop)))
(else
(let ((header (extend-header obj)))
(cond ((immediate? header)
(select (header-type header)
(((fx header/char) (fx header/true))
(set (extend-header obj) (maybe-copy-object header)) ;cdr
(modify (extend-elt obj 0) maybe-copy-object) ;car
(loop (make-pointer obj 1)))
(((fx header/stack))
(gc-scan-stack (make-pointer obj 0)
(fx+ (descriptor->fixnum obj)
(fx- (stack-length obj) 1)))
(loop (make-pointer obj (stack-length obj))))
(((fx header/text) (fx header/symbol) (fx header/bytev))
(loop (make-pointer obj (bytev-cells obj))))
(((fx header/general-vector) (fx header/unit))
(let ((len (vector-length obj)))
(do ((i 0 (fx+ i 1)))
((fx>= i len) (loop (make-pointer obj len)))
(modify (extend-elt obj i) maybe-copy-object))))
(((fx header/bignum))
(loop (make-pointer obj (bignum-length obj))))
(((fx header/slice) (fx header/foreign))
(modify (extend-elt obj 0) maybe-copy-object)
(loop (make-pointer obj 2)))
(((fx header/double-float))
(loop (make-pointer obj 2)))
(((fx header/weak-table))
(cond ((weak-semaphore-set? obj)
(modify (extend-elt obj 1) maybe-copy-object))
(else
(exchange (weak-table-vector obj)
(%table-vector (weak-table-table obj)))
(set (extend-header obj) (gc-weak-table-list))
(set (gc-weak-table-list) obj)))
(modify (extend-elt obj 0) maybe-copy-object)
(loop (make-pointer obj 2)))
(((fx header/cell))
(modify (extend-elt obj 0) maybe-copy-object)
(loop (make-pointer obj 1)))
(((fx header/weak-cell))
(set (weak-cell-contents obj) '#f)
(loop (make-pointer obj 1)))
(((fx header/weak-set))
(cond ((weak-semaphore-set? obj)
(modify (extend-elt obj 0) maybe-copy-object))
(else
(set (extend-header obj) (gc-weak-set-list))
(set (gc-weak-set-list) obj)))
(loop (make-pointer obj 1)))
(((fx header/weak-alist))
(cond ((weak-semaphore-set? obj)
(modify (extend-elt obj 0) maybe-copy-object))
(else
(set (extend-header obj) (gc-weak-alist-list))
(set (gc-weak-alist-list) obj)))
(loop (make-pointer obj 1)))
(((fx header/vcell))
(modify (extend-elt obj 0) maybe-copy-object)
(modify (extend-elt obj 1) maybe-copy-object)
(modify (extend-elt obj 2) maybe-copy-object)
(modify (extend-elt obj 3) maybe-copy-object)
(loop (make-pointer obj 4)))
(((fx header/template) 20 (fx header/interrupt-frame)
(fx header/double-float-vector) (fx header/single-float)
(fx header/ratio) (fx header/complex)
(fx header/fault-frame) 15 (fx header/task)
25 27 29 31)
(gc-error-message "Bad immediate in scan"))))
((template? header)
(set (extend-header obj)
(maybe-copy-object header))
(let ((p (template-pointer-slots header)))
(do ((i 0 (fx+ i 1)))
((fx>= i p) (loop (make-pointer
obj
(fx+ p (template-scratch-slots header)))))
(modify (extend-elt obj i) maybe-copy-object))))
(else
(set (extend-header obj) (maybe-copy-object header)) ;cdr
(modify (extend-elt obj 0) maybe-copy-object) ;car
(loop (make-pointer obj 1)))))))))